package com.jdk.learn.juc._08lock;

/**
 * Created by ricky
 * on 2018/2/1.
 *
 * 非静态方法如果加锁  默认是对象锁 this
 * 静态方法如果加锁  默认是类锁
 *
 */
public class UseLock {
    public static void main(String[] args) {
        LockDemo lockDemo=new LockDemo();
        LockDemo lockDemo2=new LockDemo();


        //线程启动顺序书写 如下   但是并不决定线程持有锁的先后顺序 可以02先执行 也可以01先执行
        //但是01和02是互斥的  当01持有锁时，02必须等待休眠结束方可有机会竞争到锁
            //同一个实例对象的情况

        // 当01持有锁时，02必须等待休眠结束方可有机会竞争到锁  可能是01先执行 也可能02先执行
         /*   new Thread(()->{
                lockDemo.getSysch01();
            }).start();
            new Thread(()->{
                lockDemo.getSysch02();
            }).start();*/

        //不同实例的情况下
        //由于持有的锁实例不是一个 所以不具有互斥性。 01在等待2000  所以永远是02先执行完毕
       /* new Thread(()->{
            lockDemo.getSysch01();
        }).start();
        new Thread(()->{
            lockDemo2.getSysch02();
        }).start();*/

        //不同实例 的类锁情况
        //由于持有的锁实例(01是对象实例锁，getStaticSysch是LockDemo.class)不是一个 所以不具有互斥性。 01在等待2000  所以永远是02先执行完毕
        //同一实例的情况下也是 类锁先执行  对象锁后执行完毕 对象锁和类锁不互斥
        new Thread(()->{
            lockDemo.getSysch01();
        }).start();
        new Thread(()->{
//            lockDemo2.getStaticSysch();
//            lockDemo2.getStaticSyschEqual();
//            lockDemo.getStaticSyschEqual();
            lockDemo.getStaticSysch();
        }).start();
    }
}

class LockDemo{

    /**
     * 对象锁  this
     */
    public synchronized void getSysch01(){
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("---------我是对象锁synchronized  01-----");
    }

    /**
     * 对象锁  this
     * */
    public synchronized void getSysch02(){
        System.out.println("---------我是对象锁synchronized  02-----");
    }

    //对象锁  this  等价与getSysch02
    public  void getSysch02Equal(){
        synchronized(this){
            System.out.println("---------我是对象锁synchronized  02equal-----");
        }

    }



    //类锁
    public static synchronized void getStaticSysch(){
        System.out.println("---------我是类锁staticsynchronized-----");
    }



    //类锁  等同于上方
    public   void getStaticSyschEqual(){
        synchronized(LockDemo.class){
            System.out.println("---------我是类锁staticsynchronizedEqual-----");
        }
    }



}
